Export CPU, GPU, and motherboard temperatures to Prometheus using windows_exporter and the LibreHardwareMonitor library.
Assumes that you already have prometheus and grafana set up.
- Windows 10/11
- windows_exporter installed
- NSSM (Non-Sucking Service Manager)
- PowerShell 5.1 or later
- Administrator privileges
- Go to LibreHardwareMonitor Releases
- Download the latest release ZIP file
- Extract to
C:\Program Files\LibreHardwareMonitor\ - You need these files from the extracted folder:
LibreHardwareMonitorLib.dllHidSharp.dll
Due to .NET Framework security restrictions, the DLLs must be placed in a trusted location.
Run PowerShell as Administrator and execute:
# Copy the DLLs to System32
Copy-Item "C:\Program Files\LibreHardwareMonitor\LibreHardwareMonitorLib.dll" "C:\Windows\System32\"
Copy-Item "C:\Program Files\LibreHardwareMonitor\HidSharp.dll" "C:\Windows\System32\"The WinRing0 driver (required for CPU temperature reading) is flagged by Windows Defender as a vulnerable driver. You must add an exclusion:
Run PowerShell as Administrator:
Add-MpPreference -ExclusionPath "C:\Program Files\LibreHardwareMonitor"Or manually:
- Open Windows Security
- Go to Virus & threat protection
- Click "Manage settings" under Virus & threat protection settings
- Scroll to Exclusions and click "Add or remove exclusions"
- Click "Add an exclusion" → "Folder"
- Select
C:\Program Files\LibreHardwareMonitor
Important: This exclusion is required because LibreHardwareMonitor uses the WinRing0 kernel driver to read CPU temperatures. Without this exclusion, Windows Defender will block the driver and CPU temperatures will not work.
The GUI application installs the WinRing0 driver needed for CPU temperature monitoring:
- Run
C:\Program Files\LibreHardwareMonitor\LibreHardwareMonitor.exeas Administrator - Wait for it to fully load (you should see temperature readings)
- Close the application
This step installs the WinRing0 driver that the library needs to read CPU temperatures.
-
Create textfile directory:
mkdir C:\prometheus_textfiles -
Update your
config.yamlto include the textfile collector:collectors: enabled: cpu,os,textfile # add other collectors as needed collector: textfile: directories: - C:\prometheus_textfiles
-
Restart windows_exporter service:
net stop windows_exporter net start windows_exporter
-
Save
collect_temps.ps1toC:\prometheus_textfiles\ -
Test the script manually first:
cd C:\prometheus_textfiles powershell -ExecutionPolicy Bypass -File .\collect_temps.ps1
You should see temperature data being collected every 10 seconds. Check that both CPU and GPU temps are present. Press Ctrl+C after verifying it works.
-
Verify the output file:
Get-Content C:\prometheus_textfiles\hardware_temps.promYou should see lines like:
hardware_temperature_celsius{hardware="Intel_Core_i7_6700K",sensor="CPU_Package"} 45.0 hardware_temperature_celsius{hardware="NVIDIA_GeForce_RTX_3070_Ti",sensor="GPU_Core"} 34.0 -
Install as a Windows service using NSSM:
cd "C:\Program Files\nssm\win64" nssm install PrometheusTemperatureCollector "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-ExecutionPolicy Bypass -NoProfile -File C:\prometheus_textfiles\collect_temps.ps1" nssm set PrometheusTemperatureCollector AppDirectory C:\prometheus_textfiles nssm set PrometheusTemperatureCollector AppStdout C:\prometheus_textfiles\service.log nssm set PrometheusTemperatureCollector AppStderr C:\prometheus_textfiles\service_error.log nssm start PrometheusTemperatureCollector
Temperature metrics are exported at your windows_exporter endpoint (default: http://localhost:9182/metrics)
# CPU Package temperature
hardware_temperature_celsius{sensor="CPU_Package"}
# GPU Core temperature
hardware_temperature_celsius{sensor="GPU_Core"}
# All CPU core temperatures
hardware_temperature_celsius{sensor=~"CPU_Core.*"}
# Max GPU temperature
max(hardware_temperature_celsius{sensor=~"GPU.*"})
# Average CPU temperature
avg(hardware_temperature_celsius{hardware=~".*Intel.*",sensor=~"CPU_Core.*"})
# Panel 1: CPU Temperature
hardware_temperature_celsius{sensor=~"CPU.*"}
# Panel 2: GPU Temperature
hardware_temperature_celsius{sensor=~"GPU.*"}
# Panel 3: Max Temperature Alert
max(hardware_temperature_celsius) > 80
- DLLs in System32: The LibreHardwareMonitor library DLLs must be in a trusted location (System32) to bypass .NET Framework security restrictions
- WinRing0 Driver: The script automatically creates and starts a Windows service for the WinRing0 kernel driver, which provides low-level access to CPU temperature sensors
- Continuous Monitoring: The script runs in a loop, collecting temperatures every 10 seconds and writing them to a Prometheus-compatible text file
- windows_exporter: Reads the text file and exposes the metrics at its HTTP endpoint for Prometheus to scrape
-
Check if the service is running:
nssm status PrometheusTemperatureCollector
-
Check the logs:
Get-Content C:\prometheus_textfiles\service.log -Tail 20 Get-Content C:\prometheus_textfiles\service_error.log -Tail 20
-
Verify the output file is being updated:
Get-Content C:\prometheus_textfiles\hardware_temps.prom
-
Verify Windows Defender exclusion is in place:
Get-MpPreference | Select-Object -ExpandProperty ExclusionPath
Should include
C:\Program Files\LibreHardwareMonitor -
Check if WinRing0 driver service is running:
Get-Service -Name "WinRing0_1_2_0"
-
If service doesn't exist or won't start:
- Make sure you ran LibreHardwareMonitor.exe as Administrator at least once
- Restart the PrometheusTemperatureCollector service:
nssm restart PrometheusTemperatureCollector
This means the WinRing0 driver isn't loaded:
- Ensure the Windows Defender exclusion for
C:\Program Files\LibreHardwareMonitoris in place - Run LibreHardwareMonitor.exe as Administrator to install the driver
- Restart the PrometheusTemperatureCollector service
-
Check Event Viewer → Windows Logs → Application for errors
-
Test the script manually:
cd C:\prometheus_textfiles powershell -ExecutionPolicy Bypass -File .\collect_temps.ps1
-
Ensure DLLs are in System32:
Test-Path C:\Windows\System32\LibreHardwareMonitorLib.dll Test-Path C:\Windows\System32\HidSharp.dll
Make sure you added the exclusion for the folder C:\Program Files\LibreHardwareMonitor, not just the driver file. The exclusion must be added before the driver is installed.
If you added the exclusion after Windows Defender already quarantined the driver:
- Open Windows Security → Virus & threat protection → Protection history
- Find the WinRing0 detection
- Click "Actions" → "Restore"
- Restart the PrometheusTemperatureCollector service
View service status:
nssm status PrometheusTemperatureCollectorRestart service:
nssm restart PrometheusTemperatureCollectorStop service:
nssm stop PrometheusTemperatureCollectorView logs:
Get-Content C:\prometheus_textfiles\service.log -Tail 50Uninstall:
nssm stop PrometheusTemperatureCollector
nssm remove PrometheusTemperatureCollector confirmThe WinRing0 driver (CVE-2020-14979) is flagged by Microsoft as vulnerable because it provides kernel-level hardware access. This vulnerability could theoretically be exploited by malware already on your system through a "Bring Your Own Vulnerable Driver" (BYOVD) attack.
Risk Assessment:
- The driver itself is not malicious
- The risk exists only if malware is already present on your system
- The driver is widely used by hardware monitoring tools (HWiNFO, MSI Afterburner, etc.)
- Adding a Windows Defender exclusion is necessary for functionality
Mitigation:
- Only use this on trusted systems
- Keep Windows and antivirus software up to date
- Monitor for unusual system behavior
- Consider using only GPU temperature monitoring if CPU temps aren't critical (no driver needed for GPU)
If you don't want to use the WinRing0 driver, you can modify the script to only monitor GPU temperatures, which don't require the driver. GPU temperature monitoring uses vendor-specific APIs that don't need kernel-level access.
This script uses LibreHardwareMonitor, which is licensed under MPL 2.0.